package com.example.demo.thread;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Code Farmer
 * @date 2020/5/23 15:44
 */

class ListNode {
    String value;
    ListNode next;

    ListNode(String value) {
        this.value = value;
    }
}

public class CasABAStackDemo {

    private static ListNode A = new ListNode("A");
    private static ListNode B = new ListNode("B");
    private static ListNode C = new ListNode("C");
    private static ListNode D = new ListNode("D");
    private static AtomicReference<ListNode> head = new AtomicReference<>(A);

    public static void main(String[] args) {

        //现将B、A依次压入栈    (head)A->B
        head.get().next = B;//先压入B

        Thread mainThread = new Thread(() -> {
            try {
                ListNode expectValue = head.get();
                Thread.sleep(3000);
                boolean result = head.compareAndSet(expectValue, B);
                System.out.println("mainThread 修改期望值是否成功：" + result);
                System.out.println("mainThread 当前head值为：" + head.get().value + "； head->next为：" + head.get().next);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread otherThread = new Thread(() -> {

//            try {
//                Thread.sleep(20);//确保主线程可以获取到锁
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            //弹出A
            ListNode newHead = head.get().next;
            head.get().next = null;
            head.set(newHead);

            //弹出B
            newHead = head.get().next;
            head.get().next = null;
            head.set(newHead);

            //压入C
            head.set(C);

            //压入D
            newHead = head.get();
            head.set(D);
            head.get().next = newHead;

            // 压入A
            newHead = head.get();
            head.set(A);
            head.get().next = newHead;
            System.out.println("otherThread head 顺序为：" + head.get().value + head.get().next.value + head.get().next.next.value);
        });

        mainThread.start();
        otherThread.start();

    }

}
